
#pragma once

#ifndef __cplusplus
#error This header requires a C++ compiler ...
#endif

#if defined(_DEBUG) || defined(DEBUG)
#	define __ENABLE_EHVEC_REPORT_CALLBACK
#endif

#include <typeinfo>

#pragma pack(push, 4)


namespace rtti
{

	typedef unsigned __int8 uint8_t;
	typedef unsigned __int32 uint32_t;

#if defined( __ENABLE_EHVEC_REPORT_CALLBACK )

	typedef void (* __eh_vec_ctor_exception_callback)( void * 			// pointer to array
													 , unsigned int		// element size
													 , int				// number of elements
													 , int				// throwing element
													 );
	void	__set_eh_vec_ctor_exception_callback( __eh_vec_ctor_exception_callback );

#endif

	typedef void (*__vtable_t)();

	inline __vtable_t const * __cast_vtable( void * __cpp_obj ) { return *( __vtable_t const **)__cpp_obj; }

	class __class_hierarchy_descriptor_t;
	
	class __complete_object_locator_t
	{
		typedef __complete_object_locator_t class_type;
	private:
		uint32_t							m_signature;
		uint32_t							m_this_offset;		//offset of this vtable in the complete class
		uint32_t							m_ctor_offset;		//constructor displacement offset
		type_info *							m_type_descriptor;	//type descriptor of the complete class
		__class_hierarchy_descriptor_t *	m_class_descriptor; //describes inheritance hierarchy

	private:
		__complete_object_locator_t();
		class_type const & operator=( class_type const &);

	public:
		inline uint32_t						signature() const			{ return m_signature; }
		inline uint32_t						offset() const				{ return m_this_offset; }
		inline uint32_t						ctor_offset() const			{ return m_ctor_offset; }
		inline type_info const *			type_descriptor() const		{ return m_type_descriptor; }
		inline __class_hierarchy_descriptor_t const *	class_descriptor() const { return m_class_descriptor; }

		inline static class_type const *	from_cpp_object( void * __cpp_obj ) 
		{
			__vtable_t const * vtable =__cast_vtable( __cpp_obj );
			return  (reinterpret_cast<class_type const *>( vtable[-1] ));
		}
	};

	//Class Hierarchy Descriptor describes the inheritance hierarchy of the class. 
	//It is shared by all COLs for a class.
	struct __base_class_descriptor_t;

	struct __base_class_array_t
	{
		__base_class_descriptor_t const * array[10];
	};

	class __class_hierarchy_descriptor_t
	{
		typedef __class_hierarchy_descriptor_t class_type;
	private:
		uint32_t					m_signature;
		uint32_t					m_attributes; //bit 0 set = multiple inheritance, bit 1 set = virtual inheritance
		uint32_t					m_base_classes_size;			//number of classes in m_num_base_classes
		__base_class_array_t const * m_base_class_array;

	private:
		__class_hierarchy_descriptor_t();
		class_type const & operator=( class_type const &);

	public:
		inline uint32_t						signature() const			{ return m_signature; }
		inline bool							multiple_inheritance() const { return (m_attributes & 0x1) > 0; }
		inline bool							virtual_inheritance() const { return (m_attributes & 0x2) > 0; }

		inline uint32_t						size() const { return m_base_classes_size; }
		inline __base_class_array_t const * base_classes() const {	return m_base_class_array; }
	};

	struct __pmd_t
	{
		int member_disp;  //member displacement
		int vbtable_disp;  //vbtable displacement
		int internal_disp;  //displacement inside vbtable
	};

	//Base Class Array describes all base classes together with information which allows 
	//compiler to cast the derived class to any of them during execution of the _dynamic_cast_ operator.
	struct __base_class_descriptor_t
	{
		type_info const *			type_descriptor; //type descriptor of the class
		uint32_t					num_contained_bases; //number of nested classes following in the Base Class Array
		__pmd_t						where;        //pointer-to-member displacement info
		uint32_t					attributes;        //flags, usually 0

		void *						compute_this_ptr( void * __cpp_obj ) const;
	};
}

#pragma pack(pop)
